package com.cloud.point.jvm;

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

import lombok.extern.slf4j.Slf4j;

/**
 * 软引用的使用
 *
 * @author 24373
 * @version 1.0
 * @date 2024-06-09 15:30
 */
@Slf4j
public class TestReference {

    private static final int _4MB = 4 * 1024 * 1024;

    public static void main(String[] args) {
        //testNormal();
        //testSoftReference();
        testWeakReference();
    }

    /**
     * 软引用使用
     * 堆内存空间有限，一些不重要的资源可以用软引用关联，空间紧张时可以回收掉
     * vm参数：-Xmx20m -XX:+PrintGCDetails -verbose:gc
     */
    private static void testSoftReference() {
        List<SoftReference<byte[]>> softList = new ArrayList<>();
        /**
         * 创建引用队列，用于回收软引用
         */
        ReferenceQueue<byte[]> queue = new ReferenceQueue<>();
        for (int i = 0; i < 5; i++) {
            /**
             * 关联引用队列，当软引用所关联的对象被回收时，软引用自己会加入引用队列中
             */
            SoftReference<byte[]> ref = new SoftReference<>(new byte[_4MB], queue);
            softList.add(ref);
        }
        /**
         * 回收为null的软引用；此时的引用队列里都是被回收的软引用对象
         */
        Reference<? extends byte[]> poll = queue.poll();
        while (poll != null) {
            softList.remove(poll);
            poll = queue.poll();
        }
        for (SoftReference<byte[]> d : softList) {
            byte[] bytes = d.get();
            System.out.println(bytes);
        }

    }

    /**
     * 弱引用使用
     */
    private static void testWeakReference() {
        List<WeakReference<byte[]>> list = new ArrayList<>();
        ReferenceQueue<byte[]> queue = new ReferenceQueue<>();
        for (int i = 0; i < 5; i++) {
            WeakReference<byte[]> ref = new WeakReference<>(new byte[_4MB], queue);
            list.add(ref);
        }
        Reference<? extends byte[]> poll = queue.poll();
        while (poll != null) {
            list.remove(poll);
            poll = queue.poll();
        }
        for (WeakReference<byte[]> d : list) {
            byte[] bytes = d.get();
            System.out.println(bytes);
        }
    }

    /**
     * 内存空间有限时，普通强引用
     */
    private static void testNormal() {
        List<byte[]> list = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            byte[] bytes = new byte[_4MB];
            list.add(bytes);
        }
        for (byte[] d : list) {
            System.out.println(d);
        }
    }

}
